package com.ecelin.entities;


import com.ecelin.utils.StrUtils;

/**
 * @author ecelin@ecelin.com
 */
public class Column {

	private String field;
	private String comment;
	private String camelName;
	private String type;
	private String javaType;
	private String notNull;
	private String key;
	private String isIndex;
	private String apiModelProperty;
	private String tableId;
	private String jsonFormat;
	private String tableField;
	private String importClass;
	private String xmlResultMap;
	private String query;

	public Column(String field, String comment, String type, String isNull, String key) {
		this.field = field;
		this.comment = comment != null ? comment.trim() : "";
		this.type = type;
		this.notNull = isNull;
		this.key = key;
		this.camelName = StrUtils.camelName(field);
		if (null == comment || "".equals(comment)) {
			this.comment = this.camelName;
		}
		javaTypeMethod();
		apiModelPropertyMethod();
		tableIdMethod();
		jsonFormatMethod();
	}

	private void javaTypeMethod() {
		String bigint = "bigint";
		String intType = "int";
		String date = "date";
		String time = "time";
		String datetime = "datetime";
		String timestamp = "timestamp";
		String binary = "binary";
		if (this.type.contains(bigint)) {
			this.javaType = "Long";
			if ("PRI".equals(this.key)) {
				this.xmlResultMap = "<id property=\"" + camelName + "\" column=\"" + field + "\" jdbcType=\"BIGINT\"/>";
			} else {
				this.xmlResultMap = "\t\t<result property=\"" + camelName + "\" column=\"" + field + "\" jdbcType=\"BIGINT\"/>";
			}
		} else if (this.type.contains(intType)) {
			this.javaType = "Integer";
			this.xmlResultMap = "\t\t<result property=\"" + camelName + "\" column=\"" + field + "\" jdbcType=\"INTEGER\"/>";
		} else if (timestamp.equals(this.type) || datetime.equals(this.type)) {
			this.javaType = "Date";
			importClass = "import java.util.Date;";
			this.xmlResultMap = "\t\t<result property=\"" + camelName + "\" column=\"" + field + "\" jdbcType=\"TIMESTAMP\"/>";
		} else if (date.equals(this.type)) {
			this.javaType = "LocalDate";
			importClass = "import java.time.LocalDate;";
			this.xmlResultMap = "\t\t<result property=\"" + camelName + "\" column=\"" + field + "\" jdbcType=\"DATE\"/>";
		} else if (time.equals(this.type)) {
			this.javaType = "LocalTime";
			importClass = "import java.time.LocalTime;";
			this.xmlResultMap = "\t\t<result property=\"" + camelName + "\" column=\"" + field + "\" jdbcType=\"TIME\"/>";
		} else if (this.type.contains(binary)) {
			this.javaType = "byte[]";
		} else {
			this.javaType = "String";
			this.xmlResultMap = "\t\t<result property=\"" + camelName + "\" column=\"" + field + "\" jdbcType=\"VARCHAR\"/>";
		}
	}

	public void apiModelPropertyMethod() {
		String note = null;
		String rn = "\r\n";
		String nr = "\n\r";
		String r = "\r";
		String n = "\n";
		String no = "NO";
		String quotationMark = "\"";
		StringBuilder sb = new StringBuilder("@ApiModelProperty(value = ");
		if (comment.contains(rn)) {
			int index = comment.indexOf(rn);
			note = comment.substring(index + 2);
			comment = comment.substring(0, index);
			sb.append(quotationMark).append(comment).append(quotationMark);
		} else if (comment.contains(nr)) {
			int index = comment.indexOf(nr);
			note = comment.substring(index + 2);
			comment = comment.substring(0, index);
			sb.append(quotationMark).append(comment).append(quotationMark);

		} else if (comment.contains(r)) {
			int index = comment.indexOf(r);
			note = comment.substring(index + 1);
			comment = comment.substring(0, index);
			sb.append(quotationMark).append(comment).append(quotationMark);

		} else if (comment.contains(n)) {
			int index = comment.indexOf(n);
			note = comment.substring(index + 1);
			comment = comment.substring(0, index);
			sb.append(quotationMark).append(comment).append(quotationMark);
		} else {
			sb.append(quotationMark).append(comment).append(quotationMark);
		}
		if (no.equals(notNull)) {
			sb.append(", required = true");
		}
		if (note != null) {
			note = note.replace(rn, " ").replace(nr, " ")
					.replace(r, " ").replace(n, " ").replace("\t", " ")
					.replace("  ", " ");
			sb.append(", notes = \"").append(note.trim()).append(quotationMark);
		}
		sb.append(")");
		this.apiModelProperty = sb.toString();
	}

	private void tableIdMethod() {
		String pri = "PRI";
		String str = "String";
		if (pri.equals(key)) {
			if (str.equals(javaType)) {
				tableId = "@TableId(type = IdType.ASSIGN_UUID)";
			} else {
				tableId = "@TableId(type = IdType.AUTO)";
			}
		}
	}

	private void jsonFormatMethod() {
		String date = "Date";
		String localDate = "LocalDate";
		String localTime = "LocalTime";
		String update = "update";
		String create = "create";
		if (date.equals(javaType)) {
			jsonFormat = "@JsonFormat(pattern = \"yyyy-MM-dd HH:mm:ss\", timezone = \"GMT+8\")";
		} else if (localDate.equals(javaType)) {
			jsonFormat = "@JsonFormat(pattern = \"yyyy-MM-dd\", timezone = \"GMT+8\")";
		} else if (localTime.equals(javaType)) {
			jsonFormat = "@JsonFormat(pattern = \"HH:mm:ss\", timezone = \"GMT+8\")";
		}
		if (jsonFormat != null) {
			if (field.toLowerCase().contains(update)) {
				tableField = "@TableField(fill = FieldFill.INSERT_UPDATE)";
			}
			if (field.toLowerCase().contains(create)) {
				tableField = "@TableField(fill = FieldFill.INSERT)";
			}
		}
	}

	public Column() {
	}

	@Override
	public String toString() {
		return "Column{" +
				"field='" + field + '\'' +
				", comment='" + comment + '\'' +
				", camelName='" + camelName + '\'' +
				", type='" + type + '\'' +
				", javaType='" + javaType + '\'' +
				", notNull='" + notNull + '\'' +
				", key='" + key + '\'' +
				", isIndex='" + isIndex + '\'' +
				", apiModelProperty='" + apiModelProperty + '\'' +
				", tableId='" + tableId + '\'' +
				", jsonFormat='" + jsonFormat + '\'' +
				", tableField='" + tableField + '\'' +
				", importClass='" + importClass + '\'' +
				", xmlResultMap='" + xmlResultMap + '\'' +
				", query='" + query + '\'' +
				'}';
	}

	public String getField() {
		return field;
	}

	public void setField(String field) {
		this.field = field;
	}

	public String getComment() {
		return comment;
	}

	public void setComment(String comment) {
		this.comment = comment;
	}

	public String getCamelName() {
		return camelName;
	}

	public void setCamelName(String camelName) {
		this.camelName = camelName;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getJavaType() {
		return javaType;
	}

	public void setJavaType(String javaType) {
		this.javaType = javaType;
	}

	public String getNotNull() {
		return notNull;
	}

	public void setNotNull(String notNull) {
		this.notNull = notNull;
	}

	public String getKey() {
		return key;
	}

	public void setKey(String key) {
		this.key = key;
	}

	public String getIsIndex() {
		return isIndex;
	}

	public void setIsIndex(String isIndex) {
		this.isIndex = isIndex;
	}

	public String getApiModelProperty() {
		return apiModelProperty;
	}

	public void setApiModelProperty(String apiModelProperty) {
		this.apiModelProperty = apiModelProperty;
	}

	public String getTableId() {
		return tableId;
	}

	public void setTableId(String tableId) {
		this.tableId = tableId;
	}

	public String getJsonFormat() {
		return jsonFormat;
	}

	public void setJsonFormat(String jsonFormat) {
		this.jsonFormat = jsonFormat;
	}

	public String getTableField() {
		return tableField;
	}

	public void setTableField(String tableField) {
		this.tableField = tableField;
	}

	public String getImportClass() {
		return importClass;
	}

	public void setImportClass(String importClass) {
		this.importClass = importClass;
	}

	public String getXmlResultMap() {
		return xmlResultMap;
	}

	public void setXmlResultMap(String xmlResultMap) {
		this.xmlResultMap = xmlResultMap;
	}

	public String getQuery() {
		return query;
	}

	public void setQuery(String query) {
		this.query = query;
	}
}

